package net.homeip.mmhg.game;

import java.util.HashMap;
import java.util.Map;

import net.homeip.mmhg.domain.Team;
import net.homeip.mmhg.game.ObtainedTask.TaskResult;

/**
 * Full info about team.
 *
 * @author ilya gerasimov
 */
public class Position {
	
	private Team team;
	private ObtainedTask obtainedTask;
		
	private Map<Integer, ObtainedTask> obtainedTasks;
	
	public enum State { PLAYING, STOPPED, FINISH_ALL_TASKS }
	
	private State state = State.PLAYING;
	
	private StatisticsService statisticService = new StatisticsService();
	
	public Position(Team team) {
		this.team = team;
		obtainedTasks = new HashMap<Integer, ObtainedTask>();
	}

	public Team getTeam() {
		return team;
	}

	public void setTeam(Team team) {
		this.team = team;
	}

	public ObtainedTask getObtainedTask() {
		return obtainedTask;
	}

	public void setObtainedTask(ObtainedTask obtainedTask) {
		this.obtainedTask = obtainedTask;
	}

	public Map<Integer, ObtainedTask> getObtainedTasks() {
		return obtainedTasks;
	}

	public void setObtainedTasks(Map<Integer, ObtainedTask> obtainedTasks) {
		this.obtainedTasks = obtainedTasks;
	}

	public void setState(State state) {
		this.state = state;
	}

	public State getState() {
		return state;
	}
	
	public int getGuessed() {
		return statisticService.getGuessed(obtainedTasks);
	}
	
	public int getRejected() {
		return statisticService.getRejected(obtainedTasks);
	}
	
	public int getTimeout() {
		return statisticService.getTimeout(obtainedTasks);
	}
	
	private class StatisticsService {
		
		private int guessed;
		private int rejected;
		private int timeout;
		private int taskNumber;
		
		private boolean isCacheValid(Map<Integer, ObtainedTask> tasks) {
			return taskNumber == tasks.size();
		}
		
		private void calculateStatistic(Map<Integer, ObtainedTask> tasks) {
			guessed = 0;
			rejected = 0;
			timeout = 0;
			for (ObtainedTask task : tasks.values()) {
				if (task.getResult() == TaskResult.REJECTED) {
					rejected++;
				} else if (task.getResult() == TaskResult.TIMEOUT) {
					timeout++;
				} else if ( (task.getResult() == TaskResult.GUESSED) ||
							(task.getResult() == TaskResult.FIRST_HINT_GUESSED) ||
							(task.getResult() == TaskResult.SECOND_HINT_GUESSED) ) {
					guessed++;
				}
			}
			taskNumber = tasks.size();
		}
		
		public int getGuessed(Map<Integer, ObtainedTask> tasks) {
			if (!isCacheValid(tasks)) {
				calculateStatistic(tasks);
			}
			return guessed;
		}
		
		public int getRejected(Map<Integer, ObtainedTask> tasks) {
			if (!isCacheValid(tasks)) {
				calculateStatistic(tasks);
			}
			return rejected;
		}
		
		public int getTimeout(Map<Integer, ObtainedTask> tasks) {
			if (!isCacheValid(tasks)) {
				calculateStatistic(tasks);
			}
			return timeout;
		}
	}
	
	public boolean isFinished() {
		return (state == State.FINISH_ALL_TASKS);
	}
	
}
